use crate::topic::Topic;

pub struct SimpleProducer<'a> {
    name: String,
    topic: &'a mut Topic
}

impl<'a> SimpleProducer<'a> {
    pub fn new(name: &str, topic: &'a mut Topic) -> Self {
        Self {
            name: String::from(name),
            topic: topic
        }
    }
    pub fn get_name(&self) -> &str {
        self.name.as_str()
    }
    pub fn get_topic(&self) -> &Topic {
        self.topic
    }
}

pub use crate::producer::{Producer, CommonError};
impl<'a> Producer for SimpleProducer<'a> {
    fn produce(&mut self, log: &[u8]) -> Result<usize, CommonError> {
        self.topic.append(log, 0, log.len())
    }
}
impl<'a> SimpleProducer<'a> {
    pub fn produce_str(&mut self, log_str: &str) -> Result<usize, CommonError>{
        self.produce(log_str.as_bytes())
    }
}

#[cfg(test)]
mod test  {
    use super::*;
    #[test]
    fn test_producer(){
        let mut topic = Topic::new("topic_name", ".");

        let log = "key:value";
        let bytes = log.as_bytes();
        // use produce()
        {
            let mut sp = SimpleProducer::new("producer", &mut topic);

            assert_eq!(bytes.len(), sp.produce(bytes).unwrap());
        }
        // use produce_str()
        {
            let mut sp = SimpleProducer::new("producer", &mut topic);

            assert_eq!(bytes.len(), sp.produce_str(log).unwrap());
        }
    }

    #[test]
    fn test_use_trait_producer(){
        let mut topic = Topic::new("topic_name", ".");

        let log = "key:value";
        let mut p = SimpleProducer::new("producer", &mut topic);

        //use trait only
        fn use_producer<T: Producer>(p: &mut T, bytes: &[u8]) {
            assert_eq!(bytes.len(), p.produce(bytes).unwrap());
        }
        use_producer(&mut p, log.as_bytes());
    }
}
